\chapter{Concurrency}
When working with parallel systems it is important to ensure concurrency problems are handled properly. If we are not considering what and how to handle it, we could run into multiple problems i.e. partial completed reservations, seats being registered twice or you do not get every seat you requested.

In this chapter we will look at considerations that have been made and how it handles concurrency problems that have been found.

\section{Seat Selection}
When more than one actor is trying to handle the same data, problems may occur, and that is if multiple customers wants to book the same seat. Locking the whole hall as soon as one seat is chosen would be a terrible solution because it would create a queue, as only one customer can use the system at the time.

We decided only to lock the selected seat(s). A chosen seat will be temporarily locked when selected and is first released upon deselecting the seat or if a timeout occurs. The advantage are no customers have to waste time going through the booking/payment session and then at the end find out someone else took their seats, although it is still possible on rare occasions. The disadvantages are that there is a lot of communications to the server and database, which could slow the performance on heavy load. We decided to lock the seats temporary, because many customers would get frustrated if they had to go through the booking process multiple times. 
\newpage
\section{Transact SQL}
To ensure that a customer can get every seat they want and not only one or two, we make a transaction which basically serves as a "all or nothing" solution. This makes the database handle all the concurrency problems related to locking seats\cite{ACID}.

The way it works is by locking a table that data is being written to, and by doing this we ensure that all the seats requested by a user will be locked, and no other seats can be locked during this period of time. However, we have set it up so you are still able to read data from the locked table. But this lead to the next problem of what happens if a user does not have an updated view of the hall. To somewhat solve this problem we have set up constrains in the database that do not allow inserts of two identical seats to a certain show meaning, if a user tries to book a seat that has already been locked by another user, the transaction will fail and everything will be rolledback and remove all seats including those that may have been available.

Below is our transaction method. It takes in all the SQL commands and the parameters for parameterized query. A connection is opened and starts a transaction where the parameters are added and each query is executed. Lastly, it tries to commit the changes made to the database, but if a seat have already been booked, an error will occur and rollback all changes made in the transaction.\\

\begin{lstlisting}
private static void TransactSQL(string[] cmd, params object[][] val)
{
    try
    {
        using (SqlConnection sqlcon = new SqlConnection(Properties.Settings.Default.DBConnectionString))
        {
            sqlcon.Open();
            SqlTransaction sqltransaction = sqlcon.BeginTransaction(IsolationLevel.ReadUncommitted, "Order");
            for (int i = 0; i < cmd.Length; i++)
            {
                if (cmd[i] == null)
                {
                    continue;
                }
                SqlCommand sqlcmd = new SqlCommand(cmd[i], sqlcon, sqltransaction);
                for (int j = 0; j < (int)(val.Length / cmd.Length); j++)
                {
                    if (val[(val.Length / cmd.Length * i) + j][0] == null)
                    {
                        continue;
                    }
                    sqlcmd.Parameters.AddWithValue(val[(val.Length / cmd.Length * i) + j][0].ToString(), val[(val.Length / cmd.Length * i) + j][1]);
                }
                sqlcmd.ExecuteScalar();
            }
            try
            {
                sqltransaction.Commit();
            }
            catch (Exception ex)
            {
                try
                {
                    sqltransaction.Rollback();
                }
                catch (Exception exce)
                {
                    throw new FaultException("Data access to server was abnormal, copy this and send to the admins of the page: " + exce.ToString());
                }
                throw new FaultException("Data access to server was abnormal, copy this and send to the admins of the page: " + ex.ToString());
            }
        }
    }
    catch (Exception ex)
    {
        throw new FaultException("Data access to server was abnormal, copy this and send to the admins of the page: " + ex.ToString());
    }
}
\end{lstlisting}